package jTorrent;

import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.apache.xmlrpc.XmlRpcException;
import org.ini4j.Ini;
import org.ini4j.Profile.Section;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;

//TODO: Installer schreiben, der auch eine Verknüpfung erstellt, die das Icon anzeigt.
public class GUI implements ActionListener
{
	private final String version = "0.3";
	private File file = new File("config.ini");
	private Image icon = getIcon(new Color(0, 80, 0));
	private JFrame frame;
	public JTabbedPane tabbedPane;
	private JMenuBar menubar;
	private JMenu action;
	private JMenuItem addTorrent;
	private JMenuItem addTorrentURL;
	private JMenu info;
	private JMenuItem about;
	private JPanel pnlTab;
	private JButton addTab;
	private int tabCount = 0;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				try
				{
					GUI window = new GUI();
					window.frame.setVisible(true);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public GUI()
	{
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize()
	{
		if (!SystemTray.isSupported()) {
            System.out.println("SystemTray is not supported");
        }
		final TrayIcon trayIcon =
                new TrayIcon(icon.getScaledInstance(16, 16, Image.SCALE_SMOOTH));
		trayIcon.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e)
            {
                frame.setVisible(true);
                frame.setExtendedState(JFrame.NORMAL);
                SystemTray.getSystemTray().remove(trayIcon);
            }

        });
        
		try
		{
			UIManager.setLookAndFeel(
			        UIManager.getSystemLookAndFeelClassName());
			UIManager.getDefaults().put("TabbedPane.tabInsets", new Insets(0, 0, 0, 2));
		}
		catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e1)
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		frame = new JFrame("jTorrent");
		frame.setIconImage(icon);
		frame.setBounds(100, 100, 700, 200);
		//=================================================================================
		//= Config.ini Saving Section
		frame.addWindowListener(new WindowAdapter()
        {
			
			//Creating Systemtray-Icon
			@Override
            public void windowIconified(WindowEvent e)
			{
                frame.setVisible(false);
                try
                {
                    SystemTray.getSystemTray().add(trayIcon);
                }
                catch (AWTException e1)
                {
                	System.out.println("Couldn't create tray Icon.");
                    e1.printStackTrace();
                }
            }
			
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.out.println("Saving Connected-Tabdata to config.ini ...");
    		    Ini ini = new Ini();
    		    ini.getConfig().setEscape(false); //Important otherwise japanese characters(e.g) are escaped and shown as \\uXXXX
    		    
    		    InputStreamReader reader = null;
				try
				{
					reader = new InputStreamReader(
					        new FileInputStream(file), "UTF-8");
				}
				catch (UnsupportedEncodingException e3)
				{
					System.out.println("Unsupported Encoding.");
				}
				catch (FileNotFoundException e3)
				{
					System.out.println("File not found.");
				}
    		    try
    			{
    		    	ini.load(reader);
    			}
    			catch (IOException e2)
    			{
    				System.out.println("Failed to read the config.ini");
    			}
    		    
    		    ini.clear();
    		    
    		    for (int i = 0; i < (tabbedPane.getTabCount() - 1); i++)
				{
					if(tabbedPane.getComponentAt(i).getClass() == TablePanel.class)
					{
						String sectionName = tabbedPane.getTitleAt(i).trim();
						ini.put(sectionName, "url", ((TablePanel)tabbedPane.getComponentAt(i)).xmlRPCFunctions.getURL());
						ini.put(sectionName, "user", ((TablePanel)tabbedPane.getComponentAt(i)).xmlRPCFunctions.getUser());
						ini.put(sectionName, "pass", ((TablePanel)tabbedPane.getComponentAt(i)).xmlRPCFunctions.getPass());
					}
				}
    		    
				try
				{
					OutputStreamWriter writer  = new OutputStreamWriter(
			                new FileOutputStream(file), "UTF-8");
					ini.store(writer);
				}
				catch (IOException e1)
				{
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
    		    
                e.getWindow().dispose();
            }
        });
		//= Config.ini Saving Section
		//=================================================================================
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		menubar = new JMenuBar();
		action = new JMenu("Actions");
		addTorrent = new JMenuItem("Add Torrentfile");
		addTorrentURL = new JMenuItem("Add Torrent via URL");
		info = new JMenu("Info");
		about = new JMenuItem("About");
		info.add(about);
		action.add(addTorrent);
		action.add(addTorrentURL);
		menubar.add(action);
		menubar.add(info);
		addTorrent.addActionListener(this);
		addTorrentURL.addActionListener(this);
		about.addActionListener(this);
		
		tabbedPane = new JTabbedPane();
		
	    // Make a small JPanel with the layout and make it non-opaque
	    pnlTab = new JPanel(new FlowLayout (FlowLayout.CENTER, 5, 0));
	    pnlTab.setOpaque (false);
	    // Create a JButton for adding the tabs
	    addTab = new JButton ("+");
	    addTab.setOpaque (false); //
	    addTab.setBorder (null);
	    addTab.setContentAreaFilled (false);
	    addTab.setFocusPainted (false);
	    addTab.setFocusable (false);
	    pnlTab.add(addTab);
	    addTab.addActionListener(this);
	    
	    //=================================================================================
	    //= Config.ini Section START
	    
    	if(file.exists())
    	{
		    Ini ini = new Ini();
		    
		    InputStreamReader reader = null;
			try
			{
				reader = new InputStreamReader(
				        new FileInputStream(file), "UTF-8");
			}
			catch (UnsupportedEncodingException e3)
			{
				// TODO Auto-generated catch block
				e3.printStackTrace();
			}
			catch (FileNotFoundException e3)
			{
				// TODO Auto-generated catch block
				e3.printStackTrace();
			}
		    try
			{
		    	ini.load(reader);
			}
			catch (IOException e2)
			{
				System.out.println("Failed to read the config.ini");
			}
		    
		    System.out.println("Reading config.ini");
		    for (String sectionName : ini.keySet())
			{
				Section section = ini.get(sectionName);
				
				System.out.println("Trying to create Tab ["+ sectionName +"]");
				XMLRPCFunctions xmlRPCFunctions = new XMLRPCFunctions();
				try
				{
					xmlRPCFunctions.estConnection(new URL(section.get("url")), section.get("user"), section.get("pass"));
				}
				catch (MalformedURLException e)
				{
					System.out.println("MalFormedURL, aborting creation of Tab ["+ sectionName +"].");
					JOptionPane.showMessageDialog(frame, "No correct URL-Format, aborting at Tab ["+ sectionName +"].", "Error", JOptionPane.ERROR_MESSAGE);
					xmlRPCFunctions = null;
					
					continue;
				}
				
				if(xmlRPCFunctions.getTorrentList() == XmlRpcException.class)
				{
					System.out.println("Connection refused, aborting creation of Tab ["+ sectionName +"]");
					JOptionPane.showMessageDialog(frame, "Connection refused, aborting creation of Tab ["+ sectionName +"]", "Error", JOptionPane.ERROR_MESSAGE);
					xmlRPCFunctions = null;
					
					continue;
				}
				else
				{
				    tabbedPane.addTab(" "+ sectionName +" ", new TablePanel(xmlRPCFunctions));
					tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new components.ButtonTabComponent(tabbedPane));
				}
			}
    	}
    	else
    	{
    		try
			{
    			file.createNewFile();
			}
			catch (IOException e)
			{
				System.out.println("Couldn't create Configuration-File.");
			}
    	}
    	//= Config.ini Section END
    	//=================================================================================
	    
		tabbedPane.addTab("+", null);
		tabbedPane.setTabComponentAt (tabbedPane.getTabCount() - 1, pnlTab);
		tabbedPane.setEnabledAt(tabbedPane.getTabCount() - 1, false);
		
		frame.getContentPane().add(menubar, BorderLayout.PAGE_START);
		frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
	}

	@Override
	public void actionPerformed(ActionEvent arg0)
	{
		if(arg0.getSource() == about)
		{
			JOptionPane.showMessageDialog(frame, "jTorrent version: "+ version +" \nProgramed by skyleo", "About", JOptionPane.INFORMATION_MESSAGE, null);
		}
		else if(arg0.getSource() == addTab)
		{
			tabbedPane.removeTabAt(tabbedPane.getTabCount() - 1);
			tabbedPane.addTab(" Tab " + (++tabCount) + " ", new ConnectPanel(this));
			tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new components.ButtonTabComponent(tabbedPane));
			tabbedPane.addTab("button", null);
			tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, pnlTab);
			tabbedPane.setEnabledAt(tabbedPane.getTabCount() - 1, false);
		}
		else
		{
			Component comp = tabbedPane.getSelectedComponent();
			if(comp != null && comp.getClass() == TablePanel.class)
			{
				if(arg0.getSource() == addTorrent)
				{
					final JFileChooser fc = new JFileChooser();
			        int returnVal = fc.showOpenDialog(frame);
		
			        if (returnVal == JFileChooser.APPROVE_OPTION)
			        {
			            File file = fc.getSelectedFile();
			            //This is where a real application would open the file.
			            System.out.println("Opening: " + file.getName());
			           ((TablePanel) comp).xmlRPCFunctions.addTorrent(file);
			        } else
			        {
			        	System.out.println("Open command cancelled by user.");
			        }
				}
				
				if(arg0.getSource() == addTorrentURL)
				{
					String input = JOptionPane.showInputDialog(frame,"URL:","http://fagl0rd.tracker.com/torrentultrafile.torrent");
					
					 ((TablePanel) comp).xmlRPCFunctions.addTorrent(input);
				}
			}
			else
			{
				JOptionPane.showMessageDialog(frame, "No Torrentsession selected.");
			}
		}
	}
	
	public Image getIcon(Color color)
	{
		BufferedImage img = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2 = img.createGraphics();

		g2.setComposite(AlphaComposite.SrcOver);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.fillOval(0, 0, 32, 32);

		g2.setComposite(AlphaComposite.SrcAtop);
		g2.setPaint(color);
		g2.fillRect(0, 0, 32, 32);
		
		g2.setPaint(Color.white);
		g2.setFont(new Font(null, Font.BOLD, 22));
		Font font = g2.getFont();
    	FontMetrics fontMetrics = g2.getFontMetrics(font);
    	int width = SwingUtilities.computeStringWidth(fontMetrics, "jT");
		g2.drawString("jT", (32 - width) / 2, 23);
		g2.dispose();
		
		return img;
	}
}